import { IconPosition, Icon, Condition } from 'types';

import { GrafanaTheme, SelectableValue, StandardEditorProps } from '@grafana/data';
import {
  Button,
  HorizontalGroup,
  IconButton,
  Input,
  RadioButtonGroup,
  Slider,
  stylesFactory,
  ThemeContext,
} from '@grafana/ui';
import { FieldNamePicker } from '../../grafana/MatchersUI/FieldNamePicker';

import { css } from 'emotion';
import React from 'react';

import * as _ from 'lodash';

const positionOptions: Array<SelectableValue<IconPosition>> = [
  {
    label: 'Upper-Left',
    value: IconPosition.UPPER_LEFT,
  },
  {
    label: 'Middle',
    value: IconPosition.MIDDLE,
  },
  {
    label: 'Upper-Right',
    value: IconPosition.UPPER_RIGHT,
  },
];

const conditionOptions: Array<SelectableValue<Condition>> = [
  {
    label: '>=',
    value: Condition.GREATER_OR_EQUAL,
  },
  {
    label: '>',
    value: Condition.GREATER,
  },
  {
    label: '=',
    value: Condition.EQUAL,
  },
  {
    label: '<',
    value: Condition.LESS,
  },
  {
    label: '<=',
    value: Condition.LESS_OR_EQUAL,
  },
];

const DEFAULT_ICON: Icon = {
  position: IconPosition.UPPER_LEFT,
  url: '',
  size: 40,
  metrics: [],
  conditions: [],
  values: [],
};

const fieldNamePickerSettings = {
  settings: { width: 24 },
} as any;

export function IconsEditor({ onChange, value, context }: StandardEditorProps<Icon[]>) {
  const icons = value;

  const addIcon = () => {
    onChange(_.concat(icons, _.cloneDeep(DEFAULT_ICON)));
  };

  const removeIcon = (idx: number) => {
    onChange(_.filter(icons, (icon, iconIdx) => iconIdx !== idx));
  };

  const addCondition = (iconIdx: number) => {
    icons[iconIdx].conditions.push(Condition.GREATER_OR_EQUAL);
    icons[iconIdx].metrics.push('');
    icons[iconIdx].values.push(0);

    onChange(icons);
  };

  const removeCondition = (iconIdx: number, conditionIdx: number) => {
    icons[iconIdx].conditions.splice(conditionIdx, 1);
    icons[iconIdx].metrics.splice(conditionIdx, 1);
    icons[iconIdx].values.splice(conditionIdx, 1);

    onChange(icons);
  };

  const onIconFieldChange = (iconIdx: number, field: keyof Icon, value: any) => {
    // @ts-ignore
    icons[iconIdx][field] = value;

    onChange(icons);
  };

  const onConditionChange = (iconIdx: number, conditionIdx: number, field: keyof Icon, value: any) => {
    // @ts-ignore
    icons[iconIdx][field][conditionIdx] = value;

    onChange(icons);
  };

  return (
    <ThemeContext.Consumer>
      {(theme) => {
        const styles = getStyles(theme.v1);
        return (
          <div>
            <div className={styles.icons}>
              {icons.map((icon, iconIdx) => {
                return (
                  <div key={iconIdx} className={styles.icon}>
                    <IconButton name="trash-alt" onClick={() => removeIcon(iconIdx)} tooltip="Delete Icon"></IconButton>
                    <div className={styles.row}>
                      <Input
                        type="url"
                        placeholder="Image URL"
                        value={icon.url}
                        onChange={(evt) => onIconFieldChange(iconIdx, 'url', (evt.target as any).value)}
                      />
                    </div>
                    <RadioButtonGroup
                      value={icon.position}
                      options={positionOptions}
                      onChange={(newVal) => onIconFieldChange(iconIdx, 'position', newVal)}
                    />
                    <div className={styles.slider}>
                      <Slider
                        value={icon.size}
                        min={1}
                        max={100}
                        step={1}
                        onAfterChange={(newVal) => onIconFieldChange(iconIdx, 'size', newVal)}
                      />
                    </div>

                    {icon.conditions.map((condition, conditionIdx) => {
                      return (
                        <div key={conditionIdx} className={styles.condition}>
                          <HorizontalGroup key={conditionIdx}>
                            <FieldNamePicker
                              context={context}
                              value={icon.metrics[conditionIdx]}
                              onChange={(newVal: any) => onConditionChange(iconIdx, conditionIdx, 'metrics', newVal)}
                              item={fieldNamePickerSettings}
                            />
                            <RadioButtonGroup
                              value={icon.conditions[conditionIdx]}
                              options={conditionOptions}
                              onChange={(newVal) => onConditionChange(iconIdx, conditionIdx, 'conditions', newVal)}
                            />
                            <Input
                              placeholder="value"
                              value={icon.values[conditionIdx]}
                              onChange={(evt) =>
                                onConditionChange(iconIdx, conditionIdx, 'values', (evt.target as any).value)
                              }
                            />
                            <IconButton
                              name="trash-alt"
                              onClick={() => removeCondition(iconIdx, conditionIdx)}
                              tooltip="Delete Condition"
                            ></IconButton>
                          </HorizontalGroup>
                        </div>
                      );
                    })}
                    <Button variant="secondary" onClick={() => addCondition(iconIdx)}>
                      Add Condition
                    </Button>
                  </div>
                );
              })}
            </div>
            <Button variant="secondary" onClick={addIcon}>
              Add Icon
            </Button>
          </div>
        );
      }}
    </ThemeContext.Consumer>
  );
}

interface IconsEditorStyles {
  icons: string;
  icon: string;
  condition: string;
  slider: string;
  row: string;
}

const getStyles = stylesFactory((theme: GrafanaTheme): IconsEditorStyles => {
  return {
    icons: css`
      display: flex;
      flex-direction: column;
      margin-bottom: ${theme.spacing.formSpacingBase * 2}px;
    `,
    icon: css`
      margin-bottom: ${theme.spacing.sm};
      border-bottom: 1px solid ${theme.colors.panelBorder};
      padding-bottom: ${theme.spacing.formSpacingBase * 2}px;

      &:last-child {
        margin-bottom: 0;
      }
    `,
    condition: css`
      margin-bottom: ${theme.spacing.xxs};
    `,
    slider: css`
      padding-bottom: ${theme.spacing.xxs};
    `,
    row: css`
      margin-bottom: ${theme.spacing.sm};
    `,
  };
});
